package com.xhwl.data.pojo.organization;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.sdata.*;
import com.xhwl.common.pojo.cent.sdata.space.OrganizationImport;
import com.xhwl.common.pojo.msg.NoticeData;
import com.xhwl.common.pojo.msg.Target;
import com.xhwl.common.utils.StringUtils;
import com.xhwl.data.dao.IEnterpriseDao;
import com.xhwl.data.dao.IOrganizationDao;
import com.xhwl.data.dao.IOrganizationManagerDao;
import com.xhwl.data.dao.IOrganizationTypeDao;
import com.xhwl.data.pojo.personal.ImportResult;
import com.xhwl.data.service.*;
import com.xhwl.data.util.CodeGenerator;
import lombok.Data;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.InputStream;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
public class OrganizationImportHandler {

    private static final Logger log = LoggerFactory.getLogger(OrganizationImportHandler.class);

    @Autowired
    private IEnterpriseService enterpriseService;
    @Autowired
    private IOrganizationService organizationService;
    @Autowired
    private IOrganizationDao organizationDao;
    @Autowired
    private IAccountService accountService;
    @Autowired
    private IOrganizationExcelErrorService organizationExcelErrorService;
    @Autowired
    private IOrganizationImportService organizationImportService;
    @Autowired
    private ICustomOrganizationTypeService customOrganizationTypeService;
    @Autowired
    IMessageCentService messageCentService;


    public void importData(InputStream inputStream, Short industryId, String originalFilename,Integer enterpriseIds,Account accountWebSocket) throws Exception {
        try (Workbook workbook = new XSSFWorkbook(inputStream)) {
            Sheet sheet = workbook.getSheetAt(0);

            // 第二行是标题行
            Row headerRow = sheet.getRow(1);

            Map<String, Integer> columnIndexMap = new HashMap<>();
            // 根据标题行填充列IndexMap
            for (int i = 0; i < headerRow.getLastCellNum(); i++) {
                Cell cell = headerRow.getCell(i);
                columnIndexMap.put(cell.getStringCellValue(), i);
            }

            DataFormatter dataFormatter = new DataFormatter();
            //记录总的条数
            int totalCount = 0;
            //记录失败的条数
            int failCount = 0;

            String errorId = UUID.randomUUID().toString().replaceAll("-", "");

            int rwo = sheet.getLastRowNum() + 1;

            for (int rowIndex = 2; rowIndex <= rwo; rowIndex++) {
                Row row = sheet.getRow(rowIndex);

                // 判断是否为空行（没有任何单元格有内容）
                if (row != null) {
                    boolean isBlankRow = true;
                    for (int j = 0; j < row.getLastCellNum(); j++) {
                        Cell cell = row.getCell(j);
                        if (cell != null && cell.getCellType() != CellType.BLANK) {
                            isBlankRow = false;
                            break;
                        }
                    }

                    if (!isBlankRow) {
                        // 使用columnIndexMap读取行中的值
                        String enterpriseCode = dataFormatter.formatCellValue(row.getCell(columnIndexMap.get("*企业编码")));
                        String enterpriseName = dataFormatter.formatCellValue(row.getCell(columnIndexMap.get("*企业名称")));
                        String parentOrgCode = dataFormatter.formatCellValue(row.getCell(columnIndexMap.get("*上级组织编码")));
                        String parentOrgName = dataFormatter.formatCellValue(row.getCell(columnIndexMap.get("*上级组织名称")));
                        String orgCode = dataFormatter.formatCellValue(row.getCell(columnIndexMap.get("组织编码")));
                        String orgName = dataFormatter.formatCellValue(row.getCell(columnIndexMap.get("*组织名称")));
                        String orgTypeName = dataFormatter.formatCellValue(row.getCell(columnIndexMap.get("*组织类型名称")));


                        //将查询出来的结果进行保存
                        OrganizationExcelDTO organizationImportDTO = new OrganizationExcelDTO();
                        organizationImportDTO.setEnterpriseCode(enterpriseCode);
                        organizationImportDTO.setEnterpriseName(enterpriseName);
                        organizationImportDTO.setParentOrgCode(parentOrgCode);
                        organizationImportDTO.setParentOrgName(parentOrgName);
                        organizationImportDTO.setOrgCode(orgCode);
                        organizationImportDTO.setOrgName(orgName);
                        organizationImportDTO.setOrgTypeName(orgTypeName);

                        //判断导入数据是否超过3000条
                        if (totalCount >= 3000){
                            log.info("单次导入组织数据超过3000条");
                            totalCount++;
                            failCount++;
                            recordError(organizationImportDTO,"超过单次导入数据最大数量",errorId);
                            continue;
                        }

                        //校验企业编码和名称
                        QueryWrapper<Enterprise> enterpriseQueryWrapper = new QueryWrapper<>();
                        enterpriseQueryWrapper.eq("code", enterpriseCode);
                        enterpriseQueryWrapper.eq("name", enterpriseName);
                        List<Enterprise> enterpriseList = enterpriseService.list(enterpriseQueryWrapper);
                        if (enterpriseList.isEmpty()){
                            failCount++;
                            totalCount++;
                            log.info("未找到对应的企业编码或企业名称,数据实体{}",organizationImportDTO);
                            recordError(organizationImportDTO,"未找到对应的企业编码或企业名称",errorId);
                            continue;
                        }
                        Enterprise rightEnterprise = enterpriseService.getById(enterpriseIds);
                        if (!rightEnterprise.getCode().equals(enterpriseCode) || !rightEnterprise.getName().equals(enterpriseName)){
                            failCount++;
                            totalCount++;
                            log.info("未找到对应的企业编码或企业名称,数据实体{}",organizationImportDTO);
                            recordError(organizationImportDTO,"未找到对应的企业编码或企业名称",errorId);
                            continue;
                        }

                        //校验上级组织编码和名称
                        QueryWrapper<Organization> organizationParentQueryWrapper = new QueryWrapper<>();
                        organizationParentQueryWrapper.eq("name",parentOrgName);
                        if (!enterpriseName.equals(parentOrgName)){
                            organizationParentQueryWrapper.eq("code",parentOrgCode);
                        }
                        organizationParentQueryWrapper.eq("enterprise_id",enterpriseList.get(0).getId());
                        List<Organization> organizationParentList = organizationService.list(organizationParentQueryWrapper);
                        if ("".equals(parentOrgName) || "".equals(parentOrgCode) || organizationParentList.isEmpty()){
                            failCount++;
                            totalCount++;
                            log.info("未找到对应的上级组织编码或上级组织名称,数据实体{}",organizationImportDTO);
                            recordError(organizationImportDTO,"未找到对应的上级组织编码或上级组织名称",errorId);
                            continue;
                        }

                        Organization organizationParent = organizationParentList.get(0);
                        Integer organizationParentId = organizationParent.getId();
                        Integer organizationParentLevel = organizationParent.getLevel();
                        //与上级企业id保持一致
                        int enterpriseId = organizationParent.getEnterpriseId();
                        //判断组织编码格式是否正确
                        if (StringUtils.isEmpty(orgCode)){
                            CodeGenerator codeGenerator = new CodeGenerator();
                            orgCode = codeGenerator.generateUniqueCode(enterpriseId,organizationService);
                        }{
                            boolean validString = isValidString(orgCode);
                            if (!validString){
                                failCount++;
                                totalCount++;
                                log.info("组织编码格式不正确,消息实体{}",organizationImportDTO);
                                recordError(organizationImportDTO,"组织编码格式不正确",errorId);
                                continue;
                            }
                        }

                        //校验组织编码是否重复
                        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
                        organizationQueryWrapper.eq("code",orgCode).eq("enterprise_id",enterpriseIds);
                        List<Organization> organizationList = organizationService.list(organizationQueryWrapper);
                        //组织编码与企业编码
                        Enterprise enterpriseServiceById = enterpriseService.getById(enterpriseIds);
                        String enterpriseServiceByIdCode = enterpriseServiceById.getCode();
                        if (orgCode.equals(enterpriseServiceByIdCode) || !organizationList.isEmpty()) {
                            failCount++;
                            totalCount++;
                            log.info("组织编码重复,消息实体{}",organizationImportDTO);
                            recordError(organizationImportDTO,"组织编码重复",errorId);
                            continue;
                        }

                        //判断组织名称长度
                        boolean validNameLengthString = isValidNameLengthString(orgName);
                        if (!validNameLengthString){
                            failCount++;
                            totalCount++;
                            log.info("组织名称格式不正确");
                            recordError(organizationImportDTO,"组织名称格式不正确",errorId);
                            continue;
                        }

                        //判断组织名是否相同
                        QueryWrapper<Organization> organizationQueryWrapperName = new QueryWrapper<>();
                        organizationQueryWrapperName.eq("parent_id",organizationParentId).eq("level",organizationParentLevel + 1);
                        List<Organization> organizationListName = organizationService.list(organizationQueryWrapperName);
                        if (null != organizationListName){
                            boolean sameName = isSameName(organizationListName, orgName);
                            if (sameName){
                                failCount++;
                                totalCount++;
                                log.info("同一上级组织下，组织名称重复");
                                recordError(organizationImportDTO,"同一上级组织下，组织名称重复",errorId);
                                continue;
                            }
                        }

                        //向组织类型表中添加数据
                        QueryWrapper<CustomOrganizationType> organizationTypeQueryWrapper  = new QueryWrapper<>();
                        organizationTypeQueryWrapper.eq("name",orgTypeName);
                        organizationTypeQueryWrapper.eq("enterprise_id",enterpriseList.get(0).getId());
                        List<CustomOrganizationType> organizationTypeList = customOrganizationTypeService.list(organizationTypeQueryWrapper);
                        if (organizationTypeList.isEmpty()){
                            failCount++;
                            totalCount++;
                            log.info("未找到对应的组织类型编码或组织类型名称,数据实体{}",organizationImportDTO);
                            recordError(organizationImportDTO,"未找到对应的组织类型名称",errorId);
                            continue;
                        }

                        Organization organizationTmp = new Organization();
                        organizationTmp.setCode(orgCode);
                        organizationTmp.setName(orgName);
                        organizationTmp.setEnterpriseId(enterpriseId);
                        organizationTmp.setParentId(organizationParentId);
                        organizationTmp.setType(4);
                        organizationTmp.setIndustryId(industryId);
                        organizationTmp.setLevel(organizationParentLevel + 1);
                        organizationTmp.setCustomOrgType(organizationTypeList.get(0).getId());
                        organizationDao.insert(organizationTmp);

                        totalCount++;
                    }
                }



            }
            OrganizationImport organizationImport = new OrganizationImport();
            organizationImport.setFileId(errorId);
            organizationImport.setFileName(originalFilename);
            int successfulCount = totalCount-failCount;
            if (failCount == 0){
                organizationImport.setImportResult("全部成功，共" + totalCount + "条");
            }else {
                organizationImport.setImportResult("成功"+successfulCount+"条，"+"失败"+failCount+"条，"+"共"+totalCount+"条");
            }

            organizationImport.setIsCompletedSuccess(failCount == 0);
            organizationImport.setEnterpriseId(enterpriseIds);
            organizationImportService.save(organizationImport);

            // 通知用户上传完毕
            NoticeData noticeData = new NoticeData();
            noticeData.setTitle("UPLOAD_ORGANIZATION_FINISHED");
            Map<String, String> map = new HashMap<>();
            map.put("total", String.valueOf(totalCount));
            map.put("fail", String.valueOf(failCount));
            map.put("fileId", errorId);
            map.put("typeId", String.valueOf(4));
            map.put("recordId", String.valueOf(organizationImport.getId()));
            noticeData.setParams(map);

            // 消息分类
            noticeData.setCategory(Arrays.asList("organization_import"));
            log.info("通知用户 {} 记录id {} 已经上传完成了", accountWebSocket.getId(), organizationImport.getId());
            try {
                Target target = new Target();
                target.setReceivers(Arrays.asList(accountWebSocket.getId().toString()));
                ResultJson resultJson = messageCentService.send("websocket", noticeData, target);
                log.info("消息发送结果 {}", JSONObject.toJSONString(resultJson));
            }catch (Exception e){
                log.error("上传完毕，通知用户失败了 {}", e.getMessage());
            }
        }
    }

    //导入失败记录
    private void recordError(OrganizationExcelDTO organizationExcelDTO,String reason,String errorId){
        //转json字符串进行存储
        String orgErrorJson = JSONObject.toJSONString(organizationExcelDTO);
        OrganizationExcelError organizationExcelError = new OrganizationExcelError();
        organizationExcelError.setReason(reason);
        organizationExcelError.setObj(orgErrorJson);
        organizationExcelError.setFileId(errorId);
        organizationExcelErrorService.save(organizationExcelError);

    }

    //判断组织编码
    public boolean isValidString(String input) {
        // 正则表达式规则，表示6-10位数字/字母组合
        String regex = "^[a-zA-Z0-9]{6,10}$";

        // 编译正则表达式为模式
        Pattern pattern = Pattern.compile(regex);

        // 创建 Matcher 对象
        Matcher matcher = pattern.matcher(input);

        // 进行匹配并返回结果
        return matcher.matches();
    }

    public boolean isValidNameLengthString(String input) {
        // 使用正则表达式匹配规则
        String pattern = "^[\\p{L}\\p{N}\\p{P}\\p{S}\\s]{2,24}$";
        return Pattern.matches(pattern, input);
    }

    public boolean isSameName(List<Organization> organizationListName,String name){
        for (Organization organization : organizationListName) {
            if (name.equals(organization.getName())){
                return true;
            }
        }
        return false;
    }
}